package com.bit.cfdi.web.vm;

import java.util.List;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.GlobalCommand;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zul.Messagebox;

import com.bit.cfdi.web.constants.CFDIConstants;
import com.bit.cfdi.web.constants.NavInfrastructure;
import com.bit.cfdi.web.domain.DBConstants;
import com.bit.cfdi.web.domain.ModulosUsuario;
import com.bit.cfdi.web.domain.Negocio;
import com.bit.cfdi.web.domain.NegocioGiro;
import com.bit.cfdi.web.domain.Usuario;
import com.bit.cfdi.web.domain.UsuarioNegocio;
import com.bit.cfdi.web.services.NegocioGiroService;
import com.bit.cfdi.web.services.NegocioService;
import com.bit.cfdi.web.services.UsuarioNegocioService;
import com.bit.cfdi.web.services.UsuarioService;
import com.bit.cfdi.web.session.SessionUtils;
import com.bit.cfdi.web.vm.negocio.WrapperGiros;
import com.bit.cfdi.web.vm.wizard.WizardViewParserPaso1;
import com.bit.cfdi.web.vm.wizard.WizardViewParserPaso2;

@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class WizardViewModel {
	
	private Logger log = LogManager.getLogger(this.getClass().getName());
	private Integer indexTabbox = 0;
	
	@WireVariable private SessionUtils sessionUtils;	
	@WireVariable private UsuarioService usuarioService;
	@WireVariable private NegocioService negocioService;
	@WireVariable private UsuarioNegocioService usuarioNegocioService;	
	@WireVariable private NegocioGiroService negocioGiroService;
	
	private WizardViewParserPaso1 step1Wizard;
	private WizardViewParserPaso2 step2Wizard;
	
	private Usuario usuario;
	private UsuarioNegocio usuarioNegocio;
	private Negocio negocio;
	private List<WrapperGiros> listGirosSelected;
	private NegocioGiro negocioGiro;
	
	//
	@Init 
	public void init()
	{
		log.info("Se ligo el VM");		
	}

	public Integer getIndexTabbox() {
		return indexTabbox;
	}

	public void setIndexTabbox(Integer indexTabbox) {
		this.indexTabbox = indexTabbox;
	}

	//
	public void SaveAndRedirect()
	{	
		//negocioGiro = new NegocioGiro();
		usuario = (Usuario)sessionUtils.getFromSession(SessionUtils.USUARIO);
		usuario.setPersona(step1Wizard.getPersonaInfo());
		negocio = step2Wizard.getNegocio();			
		usuarioNegocio = getUsuarioNegocioForNew(usuario, negocio);	
		
		boolean redirectToHome = true;
		try {
			usuarioService.save(usuario);			
		} 
		catch (DataAccessException e) {
			redirectToHome = false;
			log.warn("Ha ocurrido un error grave al intentar persistir la " +
					"información del usuario", e);
		}		
		try {
			negocioService.save(negocio);								
		} 
		catch (DataAccessException e) {
			redirectToHome = false;
			log.warn("Ha ocurrido un error grave al intentar persistir la " +
					"información del negocio", e);
		}
		try
		{
			//negocioGiro.setNegocio(negocio);
			listGirosSelected = step2Wizard.getListGirosSelected();
			if(listGirosSelected != null)
			{
				for (WrapperGiros giro : listGirosSelected) {
					negocioGiro = new NegocioGiro();
					negocioGiro.setNegocio(negocio);
					negocioGiro.setGiro(giro.getGiro());
					negocioGiro.setIsDefault(giro.getStatus());
					negocioGiroService.save(negocioGiro);
					//negocio.getGiros().add(negocioGiro);
				}			
			}			
		}
		catch(DataAccessException e)
		{
			redirectToHome = false;
			log.warn("Ha ocurrido un error grave al intentar persistir la " +
					"los giros del negocio", e);
		}
		try {
			usuarioNegocioService.save(usuarioNegocio);
		} 
		catch (DataAccessException e) {
			redirectToHome = false;
			log.warn("Ha ocurrido un error grave al intentar persistir la " +
					"información del usuario-negocio", e);
		}		
		if (redirectToHome) {
			sessionUtils.addToSession(SessionUtils.NEGOCIO,negocio);
			Executions.getCurrent().sendRedirect(
					CFDIConstants.CFDIPages.HOME_URL);			
		} else {
			Messagebox.show(
					"Ha ocurrido un error mientras se intentaban almacenar " +
					"los datos", "Error", Messagebox.OK, Messagebox.ERROR);
		}
	}
	
	//Commands
	@Command
	public void doLogOut() {
		log.info("Performing logut");
		if(sessionUtils.logOut()) {
			Executions.getCurrent().sendRedirect(
					CFDIConstants.CFDIPages.LOGIN_URL);
		}
	}

	//Global Commands
	
	@GlobalCommand
	public void assignObjStep1(@BindingParam("step1") WizardViewParserPaso1 step1Wizard)
	{
		log.info("Recibiendo la información del paso 1");	
		this.step1Wizard = step1Wizard;
	}
	
	@GlobalCommand
	public void assignObjStep2(@BindingParam("step2") WizardViewParserPaso2 step2Wizard)
	{
		log.info("Recibiendo informacion del paso 2");
		this.step2Wizard = step2Wizard;
		SaveAndRedirect();
	}
	
	@GlobalCommand
	@NotifyChange({"indexTabbox"})
	public void goUserForm()
	{
		indexTabbox = 0;
	}
	
	@GlobalCommand
	@NotifyChange({"indexTabbox"})
	public void goBusinessForm()
	{
		indexTabbox = 1;
	}
	
	private UsuarioNegocio getUsuarioNegocioForNew(final Usuario usuario, 
			final Negocio negocio) {
		
		UsuarioNegocio usuarioNegocio = new UsuarioNegocio();
		usuarioNegocio.setUsuario(usuario);
		usuarioNegocio.setStatus(DBConstants.STATUS_ACTIVE);
		usuarioNegocio.setNegocio(negocio);
	
		
		for(String currentModuloUsuario : NavInfrastructure.ALL_MODULES )
		{
			ModulosUsuario modulosUsuario = new ModulosUsuario();
			modulosUsuario.setUsuarioNegocio(usuarioNegocio);
			modulosUsuario.setNombreModulo(currentModuloUsuario);
			usuarioNegocio.getAccesos().add(modulosUsuario);
		}		
		return usuarioNegocio;
	}

}
